home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 March / PCWorld_2008-03_cd.bin / v cisle / mobiDVD / MobiDVD-1.0.0.6.exe / xulrunner / components / nsLoginManagerPrompter.js < prev    next >
Text File  |  2007-06-30  |  12KB  |  361 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is mozilla.org code.
  15.  *
  16.  * The Initial Developer of the Original Code is Mozilla Corporation.
  17.  * Portions created by the Initial Developer are Copyright (C) 2007
  18.  * the Initial Developer. All Rights Reserved.
  19.  *
  20.  * Contributor(s):
  21.  *  Justin Dolske <dolske@mozilla.com> (original author)
  22.  *
  23.  * Alternatively, the contents of this file may be used under the terms of
  24.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  25.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  26.  * in which case the provisions of the GPL or the LGPL are applicable instead
  27.  * of those above. If you wish to allow use of your version of this file only
  28.  * under the terms of either the GPL or the LGPL, and not to allow others to
  29.  * use your version of this file under the terms of the MPL, indicate your
  30.  * decision by deleting the provisions above and replace them with the notice
  31.  * and other provisions required by the GPL or the LGPL. If you do not delete
  32.  * the provisions above, a recipient may use your version of this file under
  33.  * the terms of any one of the MPL, the GPL or the LGPL.
  34.  *
  35.  * ***** END LICENSE BLOCK ***** */
  36.  
  37.  
  38. const Cc = Components.classes;
  39. const Ci = Components.interfaces;
  40.  
  41. Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
  42.  
  43. /*
  44.  * LoginManagerPromptFactory
  45.  *
  46.  * Implements nsIPromptFactory
  47.  *
  48.  * Invoked by NS_NewAuthPrompter2()
  49.  * [embedding/components/windowwatcher/src/nsPrompt.cpp]
  50.  */
  51. function LoginManagerPromptFactory() {}
  52.  
  53. LoginManagerPromptFactory.prototype = {
  54.  
  55.     classDescription : "LoginManagerPromptFactory",
  56.     contractID : "@mozilla.org/passwordmanager/authpromptfactory;1",
  57.     classID : Components.ID("{447fc780-1d28-412a-91a1-466d48129c65}"),
  58.     QueryInterface : XPCOMUtils.generateQI([Ci.nsIPromptFactory]),
  59.  
  60.     _promptService : null,
  61.     _pwmgr         : null,
  62.  
  63.     _initialized : false,
  64.  
  65.     getPrompt : function (aWindow, aIID) {
  66.  
  67.         if (!this._initialized) {
  68.             // Login manager service
  69.             this._pwmgr = Cc["@mozilla.org/login-manager;1"]
  70.                                 .getService(Ci.nsILoginManager);
  71.  
  72.             // Prompt service for user interaction
  73.             this._promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"]
  74.                                     .getService(Ci.nsIPromptService2);
  75.  
  76.             this._initialized = true;
  77.         }
  78.  
  79.         if (!aIID.equals(Ci.nsIAuthPrompt2))
  80.             throw Components.results.NS_ERROR_NO_INTERFACE;
  81.  
  82.         var prompter = new LoginManagerPrompter();
  83.         prompter.init(this._pwmgr, this._promptService, aWindow);
  84.         prompter.QueryInterface(Ci.nsIAuthPrompt2);
  85.  
  86.         return prompter;
  87.     }
  88. }; // end of LoginManagerPromptFactory implementation
  89.  
  90.  
  91.  
  92.  
  93. /* ==================== LoginManagerPrompter ==================== */
  94.  
  95.  
  96.  
  97.  
  98. /*
  99.  * LoginManagerPrompter
  100.  *
  101.  * Implements nsIAuthPrompt2.
  102.  *
  103.  * Invoked by a channel for protocol-based authentication (eg HTTP
  104.  * Authenticate, FTP login)
  105.  */
  106. function LoginManagerPrompter() {}
  107. LoginManagerPrompter.prototype = {
  108.  
  109.     QueryInterface : XPCOMUtils.generateQI([Ci.nsIAuthPrompt2]),
  110.  
  111.     __logService : null, // Console logging service, used for debugging.
  112.     get _logService() {
  113.         if (!this.__logService)
  114.             this.__logService = Cc["@mozilla.org/consoleservice;1"]
  115.                                     .getService(Ci.nsIConsoleService);
  116.         return this.__logService;
  117.     },
  118.  
  119.     _promptService : null,
  120.     _pwmgr         : null,
  121.     _window        : null,
  122.  
  123.     _debug         : false,
  124.  
  125.  
  126.     init : function (aPWManager, aPromptService, aWindow) {
  127.         this._pwmgr = aPWManager;
  128.         this._promptService = aPromptService;
  129.         this._window = aWindow;
  130.  
  131.         this.log("===== initialized =====");
  132.     },
  133.  
  134.  
  135.     /*
  136.      * log
  137.      *
  138.      * Internal function for logging debug messages to the Error Console window.
  139.      */
  140.     log : function (message) {
  141.         if (!this._debug)
  142.             return;
  143.  
  144.         dump("Pwmgr Prompter: " + message + "\n");
  145.         this._logService.logStringMessage("Pwmgr Prompter: " + message);
  146.     },
  147.  
  148.  
  149.     /*
  150.      * promptAuth
  151.      *
  152.      * Implementation of nsIAuthPrompt2.
  153.      *
  154.      * nsIChannel aChannel
  155.      * int        aLevel
  156.      * nsIAuthInformation aAuthInfo
  157.      * boolean    aConfirm
  158.      */
  159.     promptAuth : function (aChannel, aLevel, aAuthInfo, aConfirm) {
  160.         var rememberLogin = false;
  161.         var selectedLogin = null;
  162.         var checkboxLabel = null;
  163.  
  164.         this.log("===== promptAuth called =====");
  165.  
  166.         var hostname, httpRealm;
  167.         [hostname, httpRealm] = this._GetAuthKey(aChannel, aAuthInfo);
  168.  
  169.         if (this._pwmgr.getLoginSavingEnabled(hostname)) {
  170.             checkboxLabel = this.getLocalizedString("rememberPassword");
  171.  
  172.  
  173.             var foundLogins = this._pwmgr.findLogins({},
  174.                                             hostname, null, httpRealm);
  175.  
  176.             // XXX Like the original code, we can't deal with multiple
  177.             // account selection. (bug 227632)
  178.             if (foundLogins.length > 0) {
  179.                 selectedLogin = foundLogins[0];
  180.                 this._SetAuthInfo(aAuthInfo, selectedLogin.username,
  181.                                              selectedLogin.password);
  182.                 rememberLogin = true;
  183.             }
  184.         }
  185.  
  186.         // if checkboxLabel is null, the checkbox won't be shown at all.
  187.         var checkbox = { value : rememberLogin };
  188.  
  189.         var ok = this._promptService.promptAuth(this._window, aChannel,
  190.                                 aLevel, aAuthInfo, checkboxLabel, checkbox);
  191.         rememberLogin = checkbox.value;
  192.  
  193.         if (ok && rememberLogin) {
  194.             var newLogin = Cc["@mozilla.org/login-manager/loginInfo;1"]
  195.                                 .createInstance(Ci.nsILoginInfo);
  196.             newLogin.init(hostname, null, httpRealm,
  197.                             aAuthInfo.username, aAuthInfo.password,
  198.                             "", "");
  199.  
  200.             // If we didn't find an existing login, or if the username
  201.             // changed, save as a new login.
  202.             if (!selectedLogin ||
  203.                 aAuthInfo.username != selectedLogin.username) {
  204.  
  205.                 // add as new
  206.                 this.log("Adding login for " + aAuthInfo.username +
  207.                          " @ " + hostname + " (" + httpRealm + ")");
  208.                 this._pwmgr.addLogin(newLogin);
  209.  
  210.             } else if (selectedLogin &&
  211.                        aAuthInfo.password != selectedLogin.password) {
  212.  
  213.                 this.log("Updating password for " + aAuthInfo.username +
  214.                          " @ " + hostname + " (" + httpRealm + ")");
  215.                 // update password
  216.                 this._pwmgr.modifyLogin(foundLogins[0], newLogin);
  217.  
  218.             } else {
  219.                 this.log("Login unchanged, no further action needed.");
  220.                 return ok;
  221.             }
  222.         }
  223.  
  224.         return ok;
  225.     },
  226.  
  227.     asyncPromptAuth : function () {
  228.         return NS_ERROR_NOT_IMPLEMENTED;
  229.     },
  230.  
  231.     // From /netwerk/base/public/nsNetUtil.h....
  232.     /**
  233.      * This function is a helper to get a protocol's default port if the
  234.      * URI does not specify a port explicitly. Returns -1 if protocol has no
  235.      * concept of ports or if there was an error getting the port.
  236.      */
  237.     _GetRealPort : function (aURI) {
  238.         var port = aURI.port;
  239.  
  240.         if (port != -1)
  241.             return port; // explicitly specified
  242.  
  243.         // Otherwise, we have to get the default port from the protocol handler
  244.         // Need the scheme first
  245.         var scheme = aURI.scheme;
  246.  
  247.         var ioService = Cc["@mozilla.org/network/io-service;1"]
  248.                             .getService(Ci.nsIIOService);
  249.  
  250.         var handler = ioService.getProtocolHandler(scheme);
  251.         port = handler.defaultPort;
  252.  
  253.         return port;
  254.     },
  255.  
  256.  
  257.     // From: /embedding/components/windowwatcher/public/nsPromptUtils.h
  258.     // Args: nsIChannel, nsIAuthInformation, boolean, string, int
  259.     _GetAuthHostPort : function (aChannel, aAuthInfo) {
  260.  
  261.         // Have to distinguish proxy auth and host auth here...
  262.         var flags = aAuthInfo.flags;
  263.  
  264.         if (flags & (Ci.nsIAuthInformation.AUTH_PROXY)) {
  265.             // TODO: untested...
  266.             var proxied = aChannel.QueryInterface(Ci.nsIProxiedChannel);
  267.             if (!proxied)
  268.                 throw "proxy auth needs nsIProxiedChannel";
  269.  
  270.             var info = proxied.proxyInfo;
  271.             if (!info)
  272.                 throw "proxy auth needs nsIProxyInfo";
  273.  
  274.             var idnhost = info.host;
  275.             var port    = info.port;
  276.  
  277.             var idnService = Cc["@mozilla.org/network/idn-service;1"]
  278.                                 .getService(Ci.nsIIDNService);
  279.             host = idnService.convertUTF8toACE(idnhost);
  280.         } else {
  281.             var host = aChannel.URI.host;
  282.             var port = this._GetRealPort(aChannel.URI);
  283.         }
  284.  
  285.         return [host, port];
  286.     },
  287.  
  288.  
  289.     // From: /embedding/components/windowwatcher/public/nsPromptUtils.h
  290.     // Args: nsIChannel, nsIAuthInformation
  291.     _GetAuthKey : function (aChannel, aAuthInfo) {
  292.         var key = "";
  293.         // HTTP does this differently from other protocols
  294.         var http = aChannel.QueryInterface(Ci.nsIHttpChannel);
  295.         if (!http) {
  296.             key = aChannel.URI.prePath;
  297.             this.log("_GetAuthKey: got http channel, key is: " + key);
  298.             return key;
  299.         }
  300.  
  301.         var [host, port] = this._GetAuthHostPort(aChannel, aAuthInfo);
  302.  
  303.         var realm = aAuthInfo.realm;
  304.  
  305.         key += host;
  306.         key += ':';
  307.         key += port;
  308.  
  309.         this.log("_GetAuthKey got host: " + key + " and realm: " + realm);
  310.  
  311.         return [key, realm];
  312.     },
  313.  
  314.  
  315.     // From: /embedding/components/windowwatcher/public/nsPromptUtils.h
  316.     // Args: nsIAuthInformation, string, string
  317.     /**
  318.      * Given a username (possibly in DOMAIN\user form) and password, parses the
  319.      * domain out of the username if necessary and sets domain, username and
  320.      * password on the auth information object.
  321.      */
  322.     _SetAuthInfo : function (aAuthInfo, username, password) {
  323.         var flags = aAuthInfo.flags;
  324.         if (flags & Ci.nsIAuthInformation.NEED_DOMAIN) {
  325.             // Domain is separated from username by a backslash
  326.             var idx = username.indexOf("\\");
  327.             if (idx == -1) {
  328.                 aAuthInfo.username = username;
  329.             } else {
  330.                 aAuthInfo.domain   =  username.substring(0, idx);
  331.                 aAuthInfo.username =  username.substring(idx+1);
  332.             }
  333.         } else {
  334.             aAuthInfo.username = username;
  335.         }
  336.         aAuthInfo.password = password;
  337.     },
  338.  
  339.  
  340.     _bundle : null,
  341.     getLocalizedString : function (key) {
  342.  
  343.         if (!this._bundle) {
  344.             var bunService = Cc["@mozilla.org/intl/stringbundle;1"]
  345.                                 .getService(Ci.nsIStringBundleService);
  346.             this._bundle = bunService.createBundle(
  347.                         "chrome://passwordmgr/locale/passwordmgr.properties");
  348.  
  349.             if (!this._bundle)
  350.                 throw "String bundle not present!";
  351.         }
  352.  
  353.         return this._bundle.GetStringFromName(key);
  354.     }
  355. }; // end of LoginManagerPrompter implementation
  356.  
  357. var component = [LoginManagerPromptFactory];
  358. function NSGetModule(compMgr, fileSpec) {
  359.     return XPCOMUtils.generateModule(component);
  360. }
  361.